<?php
/**
 * @brief Zone class.
 *
 * @license		http://www.gnu.org/licenses/gpl-3.0.txt GNU General Public License
 * @copyright	2008 David Singer
 * @author		David Singer <david@ramaboo.com>
 * @version		1.0.0
 */

class Zone {
	protected $zone = false;
	protected $records = array();
	
	
	
	
	public function __construct() {
		
		
	}
	
	public function getZone() { return $this->zone; }
	
	public static function listZones() {
	
		$zones = array();
		$zone = false;
		$dbh = DB::connect();
		$stmt = $dbh->prepare("SELECT zone FROM resource_records WHERE type = 'SOA'");
		
		$stmt->bindColumn('zone', $zone);
		try {
			$stmt->execute();
			while ($stmt->fetch(PDO::FETCH_BOUND)) {
				$zones[] = $zone;
			}
		
		} catch (Exception $e) {
			trigger_error($e->getMessage(), E_USER_ERROR);
			return false;
		}
		
		if (!empty($zones)) {
			return $zones;
		} else {
			throw new Exception("No zones found in database.");
			return false;
		}
		
	}
	
	public function remove() {
		if (!$this->zone) {
			throw new Exception("Zone is not open.");
			return false;
		}
		
		if (!Zone::exists($this->zone, 'zone')) {
			throw new Exception("Zone $this->zone was not found and cannot be removed.");
			return false;
		}
		
		$dbh = DB::connect();
		$stmt = $dbh->prepare("DELETE FROM resource_records WHERE zone = :zone");
		$stmt->bindParam(':zone', $this->zone);
		
		try {
			$stmt->execute();
			
		
		} catch (Exception $e) {
			trigger_error($e->getMessage(), E_USER_ERROR);
			return false;
		}
		
		return true;
	}
	
	public function open($zone) {
		$zone = strtolower(trim($zone));
	
		// clear resource record array
		$this->records = array();
		
		$id = 0;
		$dbh = DB::connect();
		$stmt = $dbh->prepare("SELECT id FROM resource_records WHERE zone = :zone");
		$stmt->bindParam(':zone', $zone);
		
		$stmt->bindColumn('id', $id);
		
		$count = 0;
		try {
			$stmt->execute();
			while ($stmt->fetch(PDO::FETCH_BOUND)) {
				$record = new Record;
				$record->open($id);
				$this->records[] = $record;
				$record->close();
				$count++;
			}
		
		} catch (Exception $e) {
			trigger_error($e->getMessage(), E_USER_ERROR);
			return false;
		}
		
		if (!$count) {
			// no records found
			throw new Exception("Zone $zone was not found and cannot be opened.");
			return false;
		} else {
			// zone found
			$this->zone = $zone;
		}
		
	
		return $count;
	}
	
	public function add(Record $record) {
		// make sure record is valid
		
	/// DFIIIIIIIIIIIII
		$this->records[] = $record;
		return true;
	}
	
	public function init($zone) {
		$zone = strtolower(trim($zone));
		
		
		if ($this->zone) {
			throw new Exception("Zone $zone is already open, cannot continue.");
			return false;
		}
		
		if (!Zone::isZone($zone)) {
			throw new Exception("Zone $zone is not valid.");
			return false;
		}
		
		if (Zone::exists($zone)) {
			throw new Exception("Zone $zone already exists.");
			return false;
		}
		
		// setup default records
		
		$this->records = array();
		
		$soa = new Record;
		$soa->setZone($zone);
		$soa->setType('SOA');
		$soa->setRespContact('hostmaster');
		//////////////////// more
		
		// default a record
		$a = new Record;
		$a->setZone($zone);
		$a->setHost('@');
		$a->setType('A');
		
		
		// default cname record
		$cname = new Record;
		$cname->setZone($zone);
		$cname->setHost('@');
		$cname->setType('CNAME');
		$cname->setData('www');
		
		
		
		if (!$this->add($soa)){
			throw new Exception("Zone $zone failed to add SOA record.");
			return false;
		}
		
		if (!$this->add($a)){
			throw new Exception("Zone $zone failed to add A record.");
			return false;
		}
		
		if (!$this->add($cname)){
			throw new Exception("Zone $zone failed to add CNAME record.");
			return false;
		}
		
		
		$this->zone = $zone;
		return true;
	}
	
	function getRecordsByType($type) {
		$type = strtoupper(trim($type));
		
		if (Record::isSupportedType($type)) {
			$results = array();
			
			foreach ($this->records as $record) {
				if ($record->getType() == $type) {
					// record is the correct type, add to results
					$results[] = $record;
				}
			}
			return $results;
		} else {
			// record type is not valid
			throw new Exception("Record type $type is not valid.");
			return false;
		}
	}
	
	function getRecordCount() { return count($this->records); }
	
	public function save() {
	
		if (!$this->isValid()) {
			throw new Exception("Zone $zone is not valid.");
			return false;
		}
	
		$result = true;
		foreach ($this->records as $record) {
			$result &= $record->save();
			
		}
		
		return $result;
	}
	
	public function setRecords(array $records) {
		$valid = true;
		// check all records
		foreach ($records as $record) {
			if (!$record->isValid()) {
				// invalid record found
				throw new Exception("Record " . $record->getId() . " is not valid.");
				$valid = false;
			}
		}
	
		if ($valid) {
			$this->records = $records;
			return true;
		} else {
			return false;
		}
	}
	
	public function getRecords() {
		return $this->records;
		
	}
	
	public function isValid() {
		// checks here
		return true;
	}
	
	public static function exists($zone) {
		return Record::exists($zone, 'zone');
	}
	
	
	public static function isZone($zone) {
		return Record::isZone($zone);
	}
	
	
	
	// IMPLEMENT
	
	public static function XMLDump() {
		
		// dumps all the zones in the database to an xml file
	}
	
	public static function SQLDump() {
		
	}
	
	
}

?>